package com.example.testpic;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.text.TextUtils;
import android.util.Log;
import android.widget.GridView;
import android.widget.ImageView;

public class BitmapCache {

	public final String TAG = getClass().getSimpleName();
	private LruCache<String, Bitmap> mMemoryCache;
	public DiskLruCache mDiskLruCache;
	private ExecutorService mImageThreadPool = Executors.newFixedThreadPool(4);
	public static BitmapCache bitmapCache;

	private BitmapCache(Context context) {
		
		final int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 4;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap value) {
				// TODO Auto-generated method stub
				// Log.e(TAG,
				// "maxMem:"+maxMemory+",sizeof:"+value.getRowBytes()*value.getHeight()/1024);
				return value.getRowBytes() * value.getHeight();
			}
		};
		try {
			File cacheDir = getDiskCacheDir(context, "thumbnails");
			if (!cacheDir.exists()) {
				cacheDir.mkdir();
			}
			mDiskLruCache = DiskLruCache.openCache(context, cacheDir,
					10 * 1024 * 1024);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	public static BitmapCache getCacheInstance(Context context){
		if (bitmapCache == null) {
			bitmapCache = new BitmapCache(context);
		}		
		return bitmapCache;
	}

	public Bitmap getBitmapFromMemoryCache(String key) {
		return mMemoryCache.get(key);
	}

	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemoryCache(key) == null) {
			mMemoryCache.put(key, bitmap);
		}
	}

	public Bitmap loadBitmap(ImageView imageView, final String imagePath,
			final NativeImageCallBack nativeImageCallBack) {
		Bitmap bitmap = getBitmapFromMemoryCache(imagePath);
		final Handler imageHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				nativeImageCallBack.onImageLoader((Bitmap) msg.obj, imagePath);
			}
		};
		if (bitmap == null) {
			// BitmapWorkerTask bitmapWorkerTask = new BitmapWorkerTask();
			// bitmapWorkerTask.execute(imagePath);
			mImageThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					Log.e(TAG, "current thread name:"+Thread.currentThread().getName());
					if (imagePath != null || !imagePath.equals("")) {
						String key = MD5.Md5(imagePath);
						Bitmap mBitmap = mDiskLruCache.get(key);
						if (mBitmap == null) {
							try {
								mBitmap = Bimp.revitionImageSize(imagePath,256,256);
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							if (mBitmap != null) {
								Message message = imageHandler.obtainMessage();
								message.obj = mBitmap;
								imageHandler.sendMessage(message);
								mDiskLruCache.put(key, mBitmap); // 硬盘缓存
								addBitmapToMemoryCache(imagePath, mBitmap); // 内存缓存
							}
						} else {
							Message message = imageHandler.obtainMessage();
							message.obj = mBitmap;
							imageHandler.sendMessage(message);
							addBitmapToMemoryCache(imagePath, mBitmap); // 内存缓存
						}
					}
				}
			});
		}
		return bitmap;
	}

	/**
	 * 异步下载图片的任务
	 */
	// class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
	//
	// // 缩略图的路径
	// private String imageSourcePath;
	//
	// @Override
	// protected Bitmap doInBackground(String... params) {
	// // TODO Auto-generated method stub
	// Log.e(TAG, "current thread name:"
	// + Thread.currentThread().getName());
	// imageSourcePath = params[0];
	// Bitmap bitmap = null;
	// try {
	// if (imageSourcePath != null || !imageSourcePath.equals("")) {
	// String key = MD5.Md5(imageSourcePath);
	// bitmap = mDiskLruCache.get(key);
	// if (bitmap == null) {
	// bitmap = Bimp.revitionImageSize(imageSourcePath);
	// if (bitmap != null) {
	// mDiskLruCache.put(key, bitmap); // 硬盘缓存
	// addBitmapToMemoryCache(imageSourcePath, bitmap); // 内存缓存
	// }
	// } else {
	// addBitmapToMemoryCache(imageSourcePath, bitmap); // 内存缓存
	// }
	// }
	// } catch (IOException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return bitmap;
	// }
	//
	// @Override
	// protected void onPostExecute(Bitmap result) {
	// // TODO Auto-generated method stub
	// super.onPostExecute(result);
	// ImageView imageView = (ImageView) gridView
	// .findViewWithTag(imageSourcePath);
	// if (imageView != null && result != null) {
	// imageView.setImageBitmap(result);
	// }
	// }
	//
	// }

	// 根据传入的uniqueName获取硬盘缓存的路径
	public File getDiskCacheDir(Context context, String uniqueName) {
		String cachePath;
		if (Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState())
				|| !Environment.isExternalStorageRemovable()) {
			cachePath = context.getExternalCacheDir().getPath();
		} else {
			cachePath = context.getCacheDir().getPath();
		}
		return new File(cachePath + File.separator + uniqueName);
	}

	// 加载本地图片的回调接口
	public interface NativeImageCallBack {
		public void onImageLoader(Bitmap bitmap, String path);
	}
}
